package com.yanfan.data.controller;

import com.alibaba.fastjson2.JSONObject;
import com.yanfan.common.annotation.Anonymous;
import com.yanfan.common.annotation.Log;
import com.yanfan.common.core.controller.BaseController;
import com.yanfan.common.core.domain.AjaxResult;
import com.yanfan.common.core.page.TableDataInfo;
import com.yanfan.common.enums.BusinessType;
import com.yanfan.common.utils.poi.ExcelUtil;
import com.yanfan.iot.cache.IThingModelCache;
import com.yanfan.iot.domain.Device;
import com.yanfan.iot.domain.DeviceLog;
import com.yanfan.iot.mapper.DeviceMapper;
import com.yanfan.iot.model.HistoryModel;
import com.yanfan.iot.model.MonitorModel;
import com.yanfan.iot.model.modbus.ModbusAndThingsVO;
import com.yanfan.iot.service.IDeviceLogService;
import com.yanfan.iot.service.IThingsModelService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 设备日志Controller
 *
 * @author kerwincui
 * @date 2022-01-13
 */
@Api(tags = "设备日志模块")
@RestController
@RequestMapping("/iot/deviceLog")
public class DeviceLogController extends BaseController {
    @Autowired
    private IDeviceLogService deviceLogService;

    @Autowired
    private DeviceMapper deviceMapper;

    @Resource
    private IThingModelCache thingModelCache;

    @Autowired
    private IThingsModelService thingsModelService;

    /**
     * 查询设备日志列表
     */
    @ApiOperation("查询设备日志列表")
    //@PreAuthorize("@ss.hasPermi('iot:device:list')")
    @GetMapping("/list")
    public TableDataInfo list(DeviceLog deviceLog) {
        startPage();
        List<DeviceLog> list = deviceLogService.selectDeviceLogList(deviceLog);
        return getDataTable(list);
    }

    /**
     * 查询设备的监测数据
     */
    @ApiOperation("查询设备的监测数据")
    //@PreAuthorize("@ss.hasPermi('iot:device:list')")
    @GetMapping("/monitor")
    public TableDataInfo monitorList(DeviceLog deviceLog) {
        List<MonitorModel> list = deviceLogService.selectMonitorList(deviceLog);
        return getDataTable(list);
    }


    /**
     * 导出设备日志列表
     */
    @ApiOperation("导出设备日志列表")
    //@PreAuthorize("@ss.hasPermi('iot:device:export')")
    @Log(title = "设备日志", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, DeviceLog deviceLog) {
        List<DeviceLog> list = deviceLogService.selectDeviceLogList(deviceLog);
        ExcelUtil<DeviceLog> util = new ExcelUtil<DeviceLog>(DeviceLog.class);
        util.exportExcel(response, list, "设备日志数据");
    }

    /**
     * 获取设备日志详细信息
     */
    @ApiOperation("获取设备日志详细信息")
    //@PreAuthorize("@ss.hasPermi('iot:device:query')")
    @GetMapping(value = "/{logId}")
    public AjaxResult getInfo(@PathVariable("logId") Long logId) {
        return AjaxResult.success(deviceLogService.selectDeviceLogByLogId(logId));
    }

    /**
     * 新增设备日志
     */
    @ApiOperation("新增设备日志")
    //@PreAuthorize("@ss.hasPermi('iot:device:add')")
    @Log(title = "设备日志", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody DeviceLog deviceLog) {
        return toAjax(deviceLogService.insertDeviceLog(deviceLog));
    }

    /**
     * 修改设备日志
     */
    @ApiOperation("修改设备日志")
    //@PreAuthorize("@ss.hasPermi('iot:device:edit')")
    @Log(title = "设备日志", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody DeviceLog deviceLog) {
        return toAjax(deviceLogService.updateDeviceLog(deviceLog));
    }

    /**
     * 删除设备日志
     */
    @ApiOperation("删除设备日志")
    //@PreAuthorize("@ss.hasPermi('iot:device:remove')")
    @Log(title = "设备日志", businessType = BusinessType.DELETE)
    @DeleteMapping("/{logIds}")
    public AjaxResult remove(@PathVariable Long[] logIds) {
        return toAjax(deviceLogService.deleteDeviceLogByLogIds(logIds));
    }

    /**
     * 查询设备的历史数据
     */
    @ApiOperation("查询设备的历史数据")
    //@PreAuthorize("@ss.hasPermi('iot:device:list')")
    @PostMapping("/history")
    @Anonymous
    public AjaxResult historyList(@RequestBody DeviceLog deviceLog) {
        Map<String, List<HistoryModel>> resultMap = deviceLogService.selectHistoryList(deviceLog);
        return AjaxResult.success(resultMap);
    }

    @ApiOperation("删除设备对应的ts的历史数据")
    @GetMapping("/deleteHistoryList")
    public AjaxResult deleteHistoryList(String ts) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        DeviceLog deviceLog = new DeviceLog();
        try {
            deviceLog.setTs(formatter.parse(ts));
        } catch (Exception e) {
        }
//       FIXME lsy 功能待修复
//        int i = deviceLogService.deleteHistoryList(deviceLog.getTs(), deviceLog.getIdentity());
//        if (i > 0) {
//            return AjaxResult.success();
//        }
//        return AjaxResult.error();
        return AjaxResult.error("此功能暂无法使用");
    }

    @ApiOperation("修改设备对应的ts的历史数据")
    @GetMapping("/updateHistoryList")
    public AjaxResult updateHistoryList(DeviceLog deviceLog) {
        if (Objects.isNull(deviceLog.getLogValue())) {
            return AjaxResult.error(deviceLog.getSerialNumber() + "设备编号在：" + deviceLog.getTs() + "时间点上报" + deviceLog.getIdentity() + "的数据");
        }
        int i = deviceLogService.updateHistoryList(deviceLog);
        if (i > 0) {
            return AjaxResult.success();
        }
        return AjaxResult.error();
    }

    /**
     * 查询设备的历史数据
     */
    @ApiOperation("查询设备的历史数据")
    //@PreAuthorize("@ss.hasPermi('iot:device:list')")
    @GetMapping("/historyGroupByCreateTime")
    public TableDataInfo historyGroupByCreateTime(DeviceLog deviceLog) {
        startPage();
        List<JSONObject> list = deviceLogService.listhistoryGroupByCreateTime(deviceLog);
        return getDataTable(list);
    }

    @ApiOperation("导出时序数据")
    @PostMapping("/exportHistory")
    public void exportHistory(HttpServletResponse response, DeviceLog deviceLog) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒");
        List<HistoryModel> historyModels = deviceLogService.selectDashBoardHistorys(deviceLog);
        // 使用Stream API转换日期字段
        historyModels = historyModels.stream().map(model -> {
            // 格式化日期
            String formattedDate = dateFormat.format(model.getTime());
            // 设置日期字符串
            model.setTimeDate(formattedDate);
            return model;
        }).collect(Collectors.toList());

        //将设备编号和物模型转换对应的中文
        List<Device> thingsModelsJson = deviceMapper.getThingsModelsJson();
        Map<String, Device> map = thingsModelsJson
                .stream()
                .collect(Collectors.toMap(Device::getSerialNumber, device -> device, // 这里使用设备对象本身作为值
                                          (existingValue, newValue) -> existingValue // 如果有重复的序列号，这里选择保留现有的值
                ));

        // 使用Java 8的Stream API来更新historyModels
        historyModels.stream().filter(item->item.getIdentity()!=null).forEach(historyModel -> {
            // 获取historyModel中的id，假设id与serialNumber对应
            String serialNumber = historyModel.getSerialNumber();
            // 通过id查找map中的Device列表
            Device devices = map.get(String.valueOf(serialNumber));
            if (devices != null) {
                List<ModbusAndThingsVO> modbusConfigUnSelectThingsModel = thingsModelService.getModbusConfigUnSelectThingsModel(devices.getProductId());
                for (ModbusAndThingsVO thingsModelValueItem : modbusConfigUnSelectThingsModel) {
                    if (historyModel.getIdentity().equals(thingsModelValueItem.getIdentifier())) {
                        historyModel.setIdentity(thingsModelValueItem.getModelName());
                        if (devices.getSerialNumber().equals(serialNumber)) {
                            historyModel.setSerialNumber(devices.getDeviceName());
                        }
                        break;
                    }
                }
            }
        });
        ExcelUtil<HistoryModel> util = new ExcelUtil<HistoryModel>(HistoryModel.class);
        util.exportExcel(response, historyModels, "设备时序数据");
    }
}
